package com.hospital.billcommon.module.business;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hospital.billcommon.module.controller.dto.*;
import com.hospital.billcommon.module.entity.*;
import com.hospital.billcommon.module.mapper.*;
import com.hospital.billcommon.module.service.InpPriceService;
import com.hospital.common.core.utils.SpringContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description 住院收费实现
 * @author: liuwei
 * @create 2020/5/15 11:14 上午
 **/
public class InpChargeBusiness extends AbstractChargingBusiness<InpBillItem> {

    private QueryClinicItemMapper queryClinicItemMapper= SpringContextHolder.getBean(QueryClinicItemMapper.class);
    private InpGetMaxItemNoMapper inpGetMaxItemNoMapper=SpringContextHolder.getBean(InpGetMaxItemNoMapper.class);
    private PatientRemainMapper patientRemainMapper=SpringContextHolder.getBean(PatientRemainMapper.class);
    private InpPriceService inpPriceService=SpringContextHolder.getBean(InpPriceService.class);
    private InpGetChargeAndInsuranceTypeMapper inpGetChargeAndInsuranceTypeMapper=SpringContextHolder.getBean(InpGetChargeAndInsuranceTypeMapper.class);
    private InpGetArrearsParamMapper inpGetArrearsParamMapper= SpringContextHolder.getBean(InpGetArrearsParamMapper.class);

    private ClinicItemClassMapper clinicItemClassMapper= SpringContextHolder.getBean(ClinicItemClassMapper.class);

    @Override
    protected List<InpBillItem> getRefundData(List<RefundBillDetailVo> refundBillDetailList, RefundBillVo refundBillVo) throws Exception {
        return null;
    }

    @Override
    protected boolean insertRefundPatientData(List<InpBillItem> billItemList, RefundBillVo refundBillVo, RestTemplate restTemplate) throws Exception {
        return false;
    }

    @Override
    protected void setClassOnRcpt(InpBillItem item, String classOnInpRcpt) {
        item.setClassOnInpRcpt(classOnInpRcpt);
    }

    @Override
    protected boolean updatePatientData(List<InpBillItem> billItemList, BillDto billDto, RestTemplate restTemplate) {
        return inpPriceService.insertInpBillItemList(billItemList);
    }

    @Override
    protected boolean calculateCurrentRemain(double sum, String patientId, String visitId, String chargeType,String createChannel) {
        if (createChannel !=null && createChannel.equals("1")){
            return true;
        }
        PatientRemain inpPatientRemain=patientRemainMapper.getInpPatientRemain(patientId);
        double charge = 0.0;
        double prepay = 0.0;
        if (inpPatientRemain != null){
            charge = inpPatientRemain.getCharge();
            prepay = inpPatientRemain.getPrepay();
        }
        int canUpdateData=getArrears(patientId,visitId,prepay,charge,chargeType);
        return canUpdateData!=2;
    }

    private int getArrears(String patientId, String visitId, double prepay, double charge, String chargeType) {
        //增加绿色通道提前判断
        String greenChannelFlag = inpGetChargeAndInsuranceTypeMapper.getGreenChannelFlag(patientId, visitId);
        if (StringUtils.isNotBlank(greenChannelFlag)&&greenChannelFlag.equals("1")){
            return 1;
        }
        QueryWrapper<InpGetChargeAndInsuranceType> wrapper= new QueryWrapper<>();
        InpGetChargeAndInsuranceType inpChargeAndSub = inpGetChargeAndInsuranceTypeMapper.selectList(wrapper
                .eq("patient_id",patientId).eq("visit_id",visitId)).stream().findFirst().orElse(null);
        List<InpGetArrearsParam> inpGetArrearsParamList = inpGetArrearsParamMapper.selectList(new QueryWrapper<>());
//        List<InpGetArrearsParam> inpGetArrearsParams;
        InpGetArrearsParam inpGetArrearsParam = null;
        if (inpChargeAndSub != null) {
            if (inpChargeAndSub.getInsuranceSubTypeName() == null) {
                List<InpGetArrearsParam> inpGetArrearsParams = inpGetArrearsParamList.stream().filter(c -> c.getInsuranceTypeName().equals(chargeType)).collect(Collectors.toList());
                if (inpGetArrearsParams.size() == 1) {
                    inpGetArrearsParam = inpGetArrearsParams.get(0);
                } else {
                    inpGetArrearsParam = inpGetArrearsParamList.stream().filter(c -> "自费".equals(c.getInsuranceTypeName())).findFirst().orElse(null);
                }
            } else {
                inpGetArrearsParam = inpGetArrearsParamList.stream().filter(c -> c.getInsuranceTypeName().equals(chargeType) && c.getInsuranceSubTypeName().equals(inpChargeAndSub.getInsuranceSubTypeName())).findFirst().orElse(null);
            }
        }
        if (null != inpGetArrearsParam) {
            if (null != inpGetArrearsParam.getWarningLevel() && null != inpGetArrearsParam.getStopLevel()) {
                double d = prepay * 100 / charge;
                if (Integer.parseInt(inpGetArrearsParam.getWarningLevel()) <= d) {
                    return 0;
                } else if (Integer.parseInt(inpGetArrearsParam.getWarningLevel()) > d && d >= Integer.parseInt(inpGetArrearsParam.getStopLevel())) {
                    return 1;
                } else {
                    return 2;
                }
            } else if (null != inpGetArrearsParam.getWarningAmount() && null != inpGetArrearsParam.getStopAmount()) {
                if (prepay >= Integer.parseInt(inpGetArrearsParam.getWarningAmount())) {
                    return 0;
                } else if (prepay >= Integer.parseInt(inpGetArrearsParam.getStopAmount()) && prepay < Integer.parseInt(inpGetArrearsParam.getWarningAmount())) {
                    return 1;
                } else {
                    return 2;
                }
            }
        }
        return 0;
    }

    @Override
    protected List<InpBillItem> unpackItem(BillDto billDto) {
        List<InpBillItem> inpBillItemList = new ArrayList<>();
        if (billDto != null && billDto.getClinicTypeList() != null && billDto.getClinicTypeList().size() > 0) {
            for (ClinicType item : billDto.getClinicTypeList()) {
                boolean isPackage = clinicItemClassMapper.selectList(new QueryWrapper<>()).stream().anyMatch(c -> c.getClassCode().equals(item.getType()));
                InpGetMaxItemNo inpGetMaxItemNo = inpGetMaxItemNoMapper.selectList(new QueryWrapper<InpGetMaxItemNo>()
                        .eq("patient_id", billDto.getPatientId()).eq("visit_id", billDto.getVisitId()).orderByDesc("item_no"))
                        .stream().findFirst().orElse(null);
                int beforeNo=inpGetMaxItemNo!=null?inpGetMaxItemNo.getItemNo():1;
                for (ClinicItem item1 : item.getClinicItemList()) {
                    {
                        if (isPackage) {
                            QueryWrapper<ClinicItemBill> clinicItemBillEntityWrapper = new QueryWrapper<>();
                            clinicItemBillEntityWrapper.eq("clinic_item_class", item.getType()).eq("clinic_item_code", item1.getClinicItemCode());
                            List<ClinicItemBill> clinicItemBills = queryClinicItemMapper.selectList(clinicItemBillEntityWrapper);
                            int finalBeforeNo = beforeNo;
                            inpBillItemList.addAll(clinicItemBills.stream().map(c -> getInpBillItem(billDto.getPatientId(),c.getChargeItemClass(), c.getChargeItemCode(), c.getChargeItemSpec(),c.getAmount() * item1.getAmount(),
                                    item1.getPerformedBy(), billDto.getVisitId(), String.valueOf(Integer.parseInt(c.getChargeItemNo())+ finalBeforeNo), item1.getOperatorNo(), item1.getOrderedBy(),item1.getClinicItemCode(),item1.getOrderNo(),item1.getOrderSubNo())).collect(Collectors.toList()));
                        } else {
                            beforeNo++;
                            inpBillItemList.add(getInpBillItem(billDto.getPatientId(),item1.getItemClass(), item1.getPriceCode(),item1.getItemSpec(), item1.getAmount(), item1.getPerformedBy(), billDto.getVisitId(), String.valueOf(beforeNo), item1.getOperatorNo(), item1.getOrderedBy(),item1.getClinicItemCode(),item1.getOrderNo(),item1.getOrderSubNo()));
                        }
                    }
                }
            }
        }
        return inpBillItemList;
    }

    private InpBillItem getInpBillItem(String patientId, String itemClass, String itemCode,String itemSpec, double totalAmount,
                                       String preformedBy, String visitId, String itemNo, String operatorNo,
                                       String orderedBy,String clinicItemCode,String orderNo,String orderSubNo){
        InpBillItem inpBillItem = new InpBillItem();
        inpBillItem.setPatientId(patientId);
        inpBillItem.setItemClass(itemClass.equals("J")?"I":itemClass);
        if (StringUtils.isBlank(itemCode)){
            itemCode = clinicItemCode;
        }
        inpBillItem.setItemCode(itemCode);
        inpBillItem.setItemSpec(itemSpec);
        inpBillItem.setAmount(totalAmount);
        inpBillItem.setPerformedBy(preformedBy);
        inpBillItem.setVisitId(visitId);
        inpBillItem.setClinicItemCode(clinicItemCode);
        inpBillItem.setItemNo(itemNo);
        inpBillItem.setOperatorNo(operatorNo);
        inpBillItem.setOrderedBy(orderedBy);
        inpBillItem.setOrderNo(orderNo);
        inpBillItem.setOrderSubNo(orderSubNo);
        inpBillItem.setClassOnInpRcpt(inpPriceService.getItemRcptClass(itemCode,itemSpec) == null?itemClass:inpPriceService.getItemRcptClass(itemCode,itemSpec));
        inpBillItem.setBillingDateTime(new Date());
        return inpBillItem;
    }
}
